package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"net/http"
	"os"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: http_proxy <port>")
		os.Exit(1)
	}
	port := os.Args[1]
	listener, err := net.Listen("tcp", ":"+port)
	if err != nil {
		fmt.Println("Error starting proxy:", err)
		os.Exit(1)
	}
	fmt.Println("Listening on port", port)

	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("Error accepting connection:", err)
			continue
		}
		go handleConnection(conn)
	}
}

func handleConnection(clientConn net.Conn) {
	defer clientConn.Close()

	clientReader := bufio.NewReader(clientConn)
	req, err := http.ReadRequest(clientReader)
	if err != nil || req.Method != "GET" {
		writeErrorResponse(clientConn, "Internal Error", http.StatusInternalServerError)
		return
	}

	forwardRequest(req, clientConn)
}

func forwardRequest(req *http.Request, clientConn net.Conn) {
	host := req.Host
	targetConn, err := net.Dial("tcp", host+":80")
	if err != nil {
		writeErrorResponse(clientConn, "Internal Error", http.StatusInternalServerError)
		return
	}
	defer targetConn.Close()

	req.Header.Set("Connection", "close")
	err = req.Write(targetConn)
	if err != nil {
		writeErrorResponse(clientConn, "Internal Error", http.StatusInternalServerError)
		return
	}

	io.Copy(clientConn, targetConn)
}

func writeErrorResponse(conn net.Conn, message string, statusCode int) {
	response := fmt.Sprintf("HTTP/1.1 %d %s\r\nContent-Length: %d\r\n\r\n%s",
		statusCode, http.StatusText(statusCode), len(message), message)
	conn.Write([]byte(response))
}
